package com.boarsoft.boar.gateway.web;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.proxy.AsyncProxyServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.boarsoft.boar.gateway.GatewayConfig;
import com.boarsoft.config.core.Configable;
import com.boarsoft.soagov.svc.ServiceHandler;
import com.boarsoft.webapp.HttpServiceHandler;

/**
 * 代理从应用到soagov的HTTP请求，以便更新本地的健康检查目标节点列表
 * 
 * @author Mac_J
 *
 */
public class GatewayHttpServlet extends AsyncProxyServlet implements Configable {
	private static final long serialVersionUID = -4634847690862338373L;
	private static final Logger log = LoggerFactory.getLogger(GatewayHttpServlet.class);

	/** */
	protected HttpServiceHandler defaultHandler;
	/** */
	protected Map<String, ServiceHandler> handlerMap = new HashMap<String, ServiceHandler>();

	@Override
	public void init() throws ServletException {
		super.init();
		config();
	}

	@Override
	public void config() {
		GatewayConfig.config();
		this.setTimeout(GatewayConfig.TIMEOUT);
		log.info("Set gateway timeout = {}ms", GatewayConfig.TIMEOUT);
		// 配置每一个handler
		for (ServiceHandler h : handlerMap.values()) {
			if (h instanceof Configable) {
				((Configable) h).config();
			}
		}
	}

	@Override
	public void service(final HttpServletRequest req, final HttpServletResponse rsp) throws ServletException, IOException {
		// log.info(req.getRequestURL().toString());
		// 从请求头中提取上下文、服务消费者（客户端）版本号、测试用户白名单
		String cp = req.getPathInfo();
		// 服务上下文（group）service context
		int i = cp.substring(1).indexOf("/");
		String sc = cp.substring(0, i < 0 ? cp.length() - 1 : i + 1);
		// 根据上下文获取处理器
		ServiceHandler handler = handlerMap.get(sc);
		// 如果有匹配的处理器，调用此处理器
		HttpServiceHandler h = null;
		if (handler != null && handler instanceof HttpServiceHandler) {
			h = (HttpServiceHandler) handler;
		} else {
			h = defaultHandler;
		}
		if (h != null && h.process(req, rsp)) {
			return;
		}
		try {
			super.service(req, rsp);// URL rewrite
		} catch (Exception e) {
			log.error("Error on do service", e);
			rsp.sendError(HttpStatus.BAD_GATEWAY_502);
		}
		return;
	}

	@Override
	public String rewriteTarget(HttpServletRequest req) {
		return (String) req.getAttribute("rewriteUrl");
	}

	public Map<String, ServiceHandler> getHandlerMap() {
		return handlerMap;
	}

	public void setHandlerMap(Map<String, ServiceHandler> handlerMap) {
		this.handlerMap = handlerMap;
	}

	public HttpServiceHandler getDefaultHandler() {
		return defaultHandler;
	}

	public void setDefaultHandler(HttpServiceHandler defaultHandler) {
		this.defaultHandler = defaultHandler;
	}
}